package br.com.afi.pattern.business;

import java.io.Serializable;
import java.util.List;

import br.com.afi.pattern.converter.AbstractConverterImpl;
import br.com.afi.pattern.dao.GenericDAO;
import br.com.afi.pattern.model.Model;
import br.com.afi.pattern.vo.ValueObject;

/**
 * Essa classe abstrata possui as quatro operações básicas (Select, Insert, Update, Delete)
 * implementadas. Existem duas versões de métodos para cada tipo de operação, uma versão trabalha
 * apenas com {@link Model} (Entity) e a outra trabalha apenas com {@link ValueObject}. Para que
 * isso seja possível é necessário implementar o método {@link #createDefaultDAO()},
 * {@link #convertForward(Serializable)} e {@link #convertReverse(Serializable)}
 * 
 * @author André de Fontana Ignacio
 * @version 1.0
 * @param <E> Tipo do Model (Entity)
 * @param <ID> Tipo do Id do Model (Entity)
 * @param <V> Value Object que representa o Model (Entity).
 */
public abstract class AbstractBusinessValueObjectConverterImpl<E extends Model<ID>, ID extends Serializable, V extends ValueObject> extends AbstractConverterImpl<E, V> implements BusinessValueObjectConverter<E, ID, V>
{

	/**
	 * Construtor
	 */
	public AbstractBusinessValueObjectConverterImpl()
	{
		super();
	}

	/**
	 * Cria o DAO padrão para esta classe.
	 * 
	 * @return DAO
	 */
	public abstract GenericDAO<E, ID> createDefaultDAO();

	@Override
	public E findById( ID id )
	{
		final GenericDAO<E, ID> dao = this.createDefaultDAO();
		return dao.findById( id, false );
	}

	@Override
	public boolean existsById( ID id )
	{
		final GenericDAO<E, ID> dao = this.createDefaultDAO();
		return dao.existsById( id );
	}

	@Override
	public V findVOById( ID id )
	{
		return this.convertReverse( this.findById( id ) );
	}

	@Override
	public List<E> findAll()
	{
		final GenericDAO<E, ID> dao = this.createDefaultDAO();
		return dao.findAll();
	}

	@Override
	public List<V> findVOAll()
	{
		return this.convertListReverse( this.findAll() );
	}

	@Override
	public E save( E e ) throws BusinessException
	{
		final GenericDAO<E, ID> dao = this.createDefaultDAO();
		return dao.makePersistent( e );
	}

	@Override
	public V saveVO( V v ) throws BusinessException
	{
		final E e = this.save( this.convertForward( v ) );
		return this.convertReverse( e );
	}

	@Override
	public void delete( E e ) throws BusinessException
	{
		final GenericDAO<E, ID> dao = this.createDefaultDAO();
		dao.makeTransient( e );
	}

	@Override
	public void deleteVO( V v ) throws BusinessException
	{
		this.delete( this.convertForward( v ) );
	}

}
